#include "calibration_file.h"
#include "json/json.h"
#include "public_define.h"

#include <iostream>
#include <fstream>
#include <dirent.h>

using namespace std;
using namespace DcAdr;

CalibrationFile::CalibrationFile()
{

}

CalibrationFile::~CalibrationFile()
{

}

void CalibrationFile::deleteCalibrationFile()
{
    // 打开标定文件保存的文件目录
    DIR *dirptr = NULL;
    struct dirent *dirp;

    // 标定文件保存路径
    std::string destdir = global_data::g_calibration_root_path;

    if ((dirptr = opendir(destdir.c_str())) == NULL) //打开一个目录
    {
        Log_Info("[CalibrationFile] [deleteCalibrationFile] open failed : {}", destdir);
        return;
    }

    while (NULL != (dirp = readdir(dirptr)))
    {
        //过滤掉.和..
        if (0 == strncasecmp(dirp->d_name, ".", 1))
        {
            continue;
        }

        std::string file_name = dirp->d_name;
        std::string file_name_full = destdir + "/" + file_name;

        if (CommonOprString::prefixStrContainCheck(file_name, global_data::g_calibration_prefix) && CommonOprString::suffixStrContainCheck(file_name, global_data::g_calibration_suffix))
        {
            std::string cmd = "rm -rf " + file_name_full;
            int ret = std::system(cmd.c_str());
            Log_Info("[CalibrationFile] [deleteCalibrationFile] ret =  {}", ret);
        }
    }
    closedir(dirptr);   
}
uint8_t CalibrationFile::init()
{
    // 0:成功 1:失败
    uint8_t ret = 1;

    if (this->fileIdGetToken() != true)
    {
        return ret;
    }

    // 网络正常，下载前删除本地标定文件
    deleteCalibrationFile();

    if (this->getCalibrationFileToken() != true)
    {
        return ret;
    }

    ret = 0;
    return ret;
}

bool CalibrationFile::fileIdGetToken()
{
    Log_Info("[CalibrationFile] [getToken] fileId, get token");

    bool bGetToken = true;

    bGetToken = m_httpCommonFileId.httpReqInit(STR_DOMAIN_SYS);
    // CommonOprHttp 初始化
    if (!bGetToken)
    {
        Log_Info("[CalibrationFile] [getToken] Init http failed.");
        return false;
    }

    Log_Info("[CalibrationFile] [getToken], m_httpCommonFileId.hu_tokenMsg : {}", m_httpCommonFileId.hu_tokenMsg);

    if (!m_httpCommonFileId.hu_tokenMsg.empty())
    {
        return getFileId();
    }

    Log_Info("[CalibrationFile] [getToken] get token from cloud failed");
    return false;
}

bool CalibrationFile::getCalibrationFileToken()
{
    Log_Info("[CalibrationFile] [getCalibrationFileToken] get calibration file token");

    bool bGetToken = true;

    bGetToken = m_httpCommonFile.httpReqInit(STR_DOMAIN_FILE); //"fileDomain"
    // CommonOprHttp 初始化
    if (!bGetToken)
    {
        Log_Info("[CalibrationFile] [getCalibrationFileToken] Init http failed.");
        return false;
    }

    Log_Info("[CalibrationFile] [getCalibrationFileToken], m_httpCommonFile.hu_tokenMsg : {}", m_httpCommonFile.hu_tokenMsg);

    if (!m_httpCommonFile.hu_tokenMsg.empty())
    {
        return getCalibrationFile();
    }

    Log_Info("[CalibrationFile] [getCalibrationFileToken] get token from cloud failed");
    return false;
}

bool CalibrationFile::getFileId()
{
    Log_Info("[CalibrationFile] [getFileId] start");
    std::string getFileIdAddr = SRT_HTTPSPRE + m_httpCommonFileId.domainHost + SRT_URL_GETFILEIDLINK;

    Log_Info("[CalibrationFile][getFileId] getFileIdAddr: {}", getFileIdAddr);

    // 设置http请求头
    map<string, string> http_header;
    http_header["Content-Type"] = "application/json;charset=UTF-8";
    http_header["Accept"] = "*/*";
    http_header["X-VCS-Hu-Token"] = m_httpCommonFileId.hu_tokenMsg;
    http_header["X-VCS-Timestamp"] = CommonOprTime::getTimestr();
    http_header["X-VCS-Nonce"] = CommonOprString::GetRandStr(4);

    //无上传参数
    std::string uploadParam;

    // 获取fileId
    if (!m_httpCommonFileId.getCalibrationFile(getFileIdAddr, http_header, fileId, uploadParam, true, false))
    {
        Log_Info("[CalibrationFile][getFileId] getCalibrationFile failed, getFileId: {}", fileId);
        return false;
    }

    Log_Info("[CalibrationFile][getFileId] getCalibrationFile success, getFileId: {}", fileId);
    return true;
}

bool CalibrationFile::getCalibrationFile()
{
    Log_Info("[CalibrationFile] [getCalibrationFile] start");

    Json::Reader reader;
    Json::Value root;
    Json::FastWriter writer;

    // https://{fileDomain}/tu-apigw/filecenter/api/open/v3/cloud-disk/get-download-link
    std::string fileDownloadLink = SRT_HTTPSPRE + m_httpCommonFile.domainHost + SRT_URL_GETCALIBRATIONFILELINK;

    Log_Info("[CalibrationFile][getCalibrationFile] CalibrationFile fileDownloadLink: {}", fileDownloadLink);

    // 设置http请求头
    map<string, string> http_header;
    http_header["Content-Type"] = "application/json";
    // http_header["Accept"] = "*/*";
    http_header["X-VCS-Hu-Token"] = m_httpCommonFile.hu_tokenMsg;
    http_header["X-VCS-Timestamp"] = CommonOprTime::getTimestr();
    http_header["X-VCS-Nonce"] = CommonOprString::GetRandStr(4);

    // 获取下载链接
    // 解析json中data字段获取fileId
    if ((!reader.parse(fileId, root)) || (!root.isMember("data")))
    {
        Log_Info("[CalibrationFile] [getCalibrationFile] rgetFileId parse error!");
        return false;
    }

    // 判断fileId是否为空
    Json::Value fileId = root["data"];
    if (fileId.isNull())
    {
        Log_Info("[CalibrationFile] [getCalibrationFile] fileId is NULL");
        return false;
    }

    std::string strFileId = JsonToValue<std::string>(root["data"]);
    Json::Value reqParam;
    reqParam["linkType"] = "ONCE";
    reqParam["authType"] = "Hu";
    reqParam["fileId"] = strFileId;

    std::string uploadParam = writer.write(reqParam);

    Log_Info("[CalibrationFile] [getCalibrationFile] uploadParam: {}", uploadParam);

    if (!m_httpCommonFile.getCalibrationFile(fileDownloadLink, http_header, getFileDownloadLink, uploadParam, true, false))
    {
        Log_Info("[CalibrationFile][getCalibrationFile] getCalibrationFile failed, getFileDownloadLink: {}", getFileDownloadLink);
        return false;
    }

    Log_Info("[CalibrationFile][getCalibrationFile] getCalibrationFile success, getFileDownloadLink: {}", getFileDownloadLink);

    // 上传文件
    // 解析json中data字段获取fileId
    if ((!reader.parse(getFileDownloadLink, root)) || (!root.isMember("data")))
    {
        Log_Info("[CalibrationFile] [getCalibrationFile] getFileDownloadLink parse error!");
        return false;
    }

    Json::Value data = root["data"];

    if (!(data.isObject()) || !(data.isMember("downloadLink")))
    {
        Log_Info("[CalibrationFile] [getCalibrationFile] getFileDownloadLink downloadLink is NULL!");
        return false;
    }

    std::string downloadLink = JsonToValue<std::string>(data["downloadLink"]);

    Log_Info("[CalibrationFile] [getCalibrationFile] downloadLink = {}", downloadLink);

    //无返回值
    std::string resposeBuff;
    //无上传参数
    std::string getFileUploadParam;

    if (!m_httpCommonFile.getCalibrationFile(downloadLink, http_header, resposeBuff, getFileUploadParam, true, true))
    {
        Log_Info("[CalibrationFile][getCalibrationFile] getCalibrationFile failed, getFileDownloadLink: {}", getFileDownloadLink);
        return false;
    }

    return true;
}